package com.luo.d3s.ext.aop.exception.handler;

import com.luo.d3s.core.application.dto.MultiResponse;
import com.luo.d3s.core.application.dto.PageResponse;
import com.luo.d3s.core.application.dto.Response;
import com.luo.d3s.core.application.dto.SingleResponse;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * D3s异常处理器
 *
 * @author luohq
 * @date 2023-02-01 10:32
 */
public interface D3sExceptionHandler {

    /**
     * 处理异常
     *
     * @param method    执行方法
     * @param throwable 异常
     * @return 返回结果
     */
    Object handleException(Method method, Throwable throwable);

    /**
     * 返回结果是否是D3s响应对象
     *
     * @param method 执行方法
     * @return 是否是D3s响应对象
     */
    default Boolean isReturnD3sResponse(Method method) {
        if (Objects.isNull(method)) {
            return true;
        }
        return Response.class.isAssignableFrom(method.getReturnType());
    }

    /**
     * 根据Response具体类型包装响应结果
     *
     * @param method     执行方法
     * @param errCode    错误码
     * @param errMessage 错误提示信息
     * @return 响应结果
     */
    default Object wrapErrorResp(Method method, String errCode, String errMessage) {
        Class<?> respClass = this.getReturnTypeFromMethod(method);
        return this.wrapErrorResp(respClass, errCode, errMessage);
    }

    /**
     * 根据Response具体类型包装响应结果
     *
     * @param respClass  Response具体类型
     * @param errCode    错误码
     * @param errMessage 错误提示信息
     * @return 响应结果
     */
    default Object wrapErrorResp(Class<?> respClass, String errCode, String errMessage) {
        if (SingleResponse.class.equals(respClass)) {
            return SingleResponse.buildFailure(errCode, errMessage);
        } else if (MultiResponse.class.equals(respClass)) {
            return MultiResponse.buildFailure(errCode, errMessage);
        } else if (PageResponse.class.equals(respClass)) {
            return PageResponse.buildFailure(errCode, errMessage);
        } else if (Response.class.equals(respClass)) {
            return Response.buildFailure(errCode, errMessage);
        } else {
            return null;
        }
    }

    /**
     * 获取方法的返回值（若方法为空则默认返回Response）
     *
     * @param method 方法
     * @return 返回值类型
     */
    default Class<?> getReturnTypeFromMethod(Method method) {
        if (Objects.nonNull(method)) {
            return method.getReturnType();
        }
        return Response.class;
    }

    /**
     * 根据Response具体类型包装响应结果
     *
     * @param respClass  Response具体类型
     * @param errCode    错误码
     * @param errMessage 错误提示信息
     * @return 响应结果
     */
    default Object wrapSuccessResp(Class<?> respClass, String errCode, String errMessage) {
        Response response = null;
        if (SingleResponse.class.equals(respClass)) {
            response = SingleResponse.buildSuccess();
        } else if (MultiResponse.class.equals(respClass)) {
            response = MultiResponse.buildSuccess();
        } else if (PageResponse.class.equals(respClass)) {
            response = PageResponse.buildSuccess();
        } else if (Response.class.equals(respClass)) {
            response = Response.buildSuccess();
        }
        if (null != response) {
            response.setErrCode(errCode);
            response.setErrMessage(errMessage);
        }
        return response;
    }
}
